<html>
<head><meta charset="utf-8"><title>ignoring in VFS · t-compiler/rust-analyzer · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/index.html">t-compiler/rust-analyzer</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html">ignoring in VFS</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="160205505"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160205505" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160205505">(Mar 07 2019 at 15:06)</a>:</h4>
<p><span class="user-mention" data-user-id="204303">@vipentti</span> you've recently tweaked ignoring logic in the VFS, would you be interested in making it more generic?</p>
<p>Specifically, I think VFS can accept paris of <code>(PathBuf, Box&lt;dyn Fn(&amp;RelativePath)&gt;)</code> as source roots (i.e, source root + exclusion pattern), and use that instead of hardcoded logic.</p>
<p>I think it makes sense to say that the filtering function is only called for <strong>files</strong> and change the implementation inside VFS such that <code>if path.is_dir()</code> is an implementation detail. We probaly want to use a <code>struct</code> with good names instead of a pair as well.</p>
<p>With that interface in place, we can move hard-coded logic about <code>.rs</code> and <code>ndoe_modules</code> out of the VFS and into <code>ra_lsp_server</code>.</p>



<a name="160205599"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160205599" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160205599">(Mar 07 2019 at 15:07)</a>:</h4>
<p>Sounds good, Yeah I was thinking about that too. That way <code>ra_vfs</code> could be used in a more generic way and not just with rust files</p>



<a name="160206119"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160206119" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160206119">(Mar 07 2019 at 15:13)</a>:</h4>
<p>yeah... We really should have done this when extracting VFS to a separate repo. Now we have to coordinate updates to both repos, or use the <code>[patch]</code> section of Cargo.toml</p>



<a name="160206499"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160206499" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160206499">(Mar 07 2019 at 15:17)</a>:</h4>
<p>Yeah, that's unfortunate but hopefully should not be too bad to do now</p>



<a name="160209789"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160209789" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160209789">(Mar 07 2019 at 15:56)</a>:</h4>
<p>The reason for the <code>(PathBuf, Box&lt;dyn Fn(&amp;RelativePath)&gt;)</code> is so that we can have different exclusions for different paths ? like ignoring <code>test|benchmark|example</code> from external crates</p>



<a name="160210144"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160210144" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160210144">(Mar 07 2019 at 16:00)</a>:</h4>
<p>Yeah</p>



<a name="160210209"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160210209" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160210209">(Mar 07 2019 at 16:01)</a>:</h4>
<p>I imagine long-term users should be able to override exclusion manually as well</p>



<a name="160281348"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160281348" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160281348">(Mar 08 2019 at 11:16)</a>:</h4>
<p>Should the exclusion happen in <code>Roots</code> still ? e.g. should the callback be passed and stored together with the <code>RootData</code> ?</p>



<a name="160282900"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160282900" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160282900">(Mar 08 2019 at 11:47)</a>:</h4>
<p>Currently the VFS is provided with a list of root directories right ? and then the individual files are read and the folders watched in <code>io.rs</code> ?</p>



<a name="160284598"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160284598" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160284598">(Mar 08 2019 at 12:24)</a>:</h4>
<p>Yeah, the callback should be stored as a part of <code>RootData</code></p>



<a name="160284605"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160284605" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160284605">(Mar 08 2019 at 12:24)</a>:</h4>
<blockquote>
<p>Currently the VFS is provided with a list of root directories right ? and then the individual files are read and the folders watched in <a href="http://io.rs" target="_blank" title="http://io.rs">io.rs</a> ?</p>
</blockquote>
<p>Yeap</p>



<a name="160284625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160284625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160284625">(Mar 08 2019 at 12:25)</a>:</h4>
<p>Specifically, <code>roots</code> is what answers the question "to which root does this path belong"</p>



<a name="160284635"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160284635" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160284635">(Mar 08 2019 at 12:25)</a>:</h4>
<p>and <code>io</code> is the thing which actually reads the contents of files from disk</p>



<a name="160286855"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160286855" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160286855">(Mar 08 2019 at 13:03)</a>:</h4>
<p>I guess since the current method of filtering files works, there should not be performance concerns regarding filtering ? I mean currently you could technically attempt to load files from node_modules but then the files would be ignored based in <code>is_excluded</code></p>



<a name="160286975"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160286975" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160286975">(Mar 08 2019 at 13:05)</a>:</h4>
<p>it's important to avoid scanning the node_modules folder though</p>



<a name="160287254"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160287254" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160287254">(Mar 08 2019 at 13:09)</a>:</h4>
<p>Yeah, I imagine being able to exclude whole directories from scanning would be useful in general</p>



<a name="160289205"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160289205" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160289205">(Mar 08 2019 at 13:34)</a>:</h4>
<p>What do you think about instead of returning <code>bool</code> from the callback, we'll return some enum with two variants e.g.</p>
<div class="codehilite"><pre><span></span><span class="k">pub</span><span class="w"> </span><span class="k">enum</span> <span class="nc">MatchResult</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="sd">/// Keep the file</span>
<span class="w">    </span><span class="n">Keep</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="sd">/// Exclude the file</span>
<span class="w">    </span><span class="n">Exclude</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>Naming tbd but that way they callback can be used to exclude files by default or to keep files by default, I find <code>bool</code> to be ambiguous in this case.</p>



<a name="160290252"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160290252" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160290252">(Mar 08 2019 at 13:49)</a>:</h4>
<p>excellent idea!</p>



<a name="160290261"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160290261" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160290261">(Mar 08 2019 at 13:49)</a>:</h4>
<p><code>enum Inclusion { Include, Exclude }</code></p>



<a name="160290539"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160290539" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160290539">(Mar 08 2019 at 13:52)</a>:</h4>
<p>hmm, still not quite sure what to do regarding folders, I mean it doesn't make sense to start watching folders that will be ignored, meaning if you add <code>a/{nested|node_modules}</code> as root but you want to ignore <code>node_modules</code> it would make sense to only watch <code>a/nested</code> and skip further processing of content in <code>node_modules</code> ?</p>



<a name="160290610"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160290610" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160290610">(Mar 08 2019 at 13:54)</a>:</h4>
<p>yeah, I guess my original intention "make exclusion care only about files" was wrong</p>



<a name="160290664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160290664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160290664">(Mar 08 2019 at 13:54)</a>:</h4>
<p>we do need to care about folders somehow</p>



<a name="160290701"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160290701" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160290701">(Mar 08 2019 at 13:55)</a>:</h4>
<p>Can we say that a path to folder must include trailing <code>/</code> to distinguish two cases without making a syscall?</p>



<a name="160290729"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160290729" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160290729">(Mar 08 2019 at 13:55)</a>:</h4>
<p>Alternatively, we can make something like <code>{ IncludeIfFile, IncludeIfDir, Exclude }</code></p>



<a name="160290852"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160290852" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160290852">(Mar 08 2019 at 13:57)</a>:</h4>
<p>hmm I wonder if we could run some folder_based filtering already in the initial <code>Roots</code> creation, meaning if you have a root <code>a/node_modules</code> and it matches an ignore, we'll not process it further and drop it from the roots</p>



<a name="160291159"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160291159" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160291159">(Mar 08 2019 at 14:00)</a>:</h4>
<p>Although I guess we'd still need to do some further filtreing in <code>io</code> since that one walks the directory tree ?</p>



<a name="160291246"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160291246" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160291246">(Mar 08 2019 at 14:01)</a>:</h4>
<p>I think filtering during creating is isomorphic to filtering during initial scan</p>



<a name="160291634"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160291634" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160291634">(Mar 08 2019 at 14:05)</a>:</h4>
<p>True, though during initial scan you'll recursively go down the roots</p>



<a name="160291730"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160291730" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160291730">(Mar 08 2019 at 14:06)</a>:</h4>
<p>yeah, it's more correct to say that we do strictly more work during initial scan anyway</p>



<a name="160292214"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160292214" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160292214">(Mar 08 2019 at 14:11)</a>:</h4>
<p>hmm actually it might not be a problem, if the <code>roots</code> don't contain the <code>a/node_modules</code> exclude_callback will only be called once when the WalkDir happens to attempt reading it, and then the exclusion should only occur once without further processing of the folders / files inside <code>node_modules</code></p>



<a name="160294132"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160294132" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160294132">(Mar 08 2019 at 14:32)</a>:</h4>
<blockquote>
<p>Can we say that a path to folder must include trailing <code>/</code> to distinguish two cases without making a syscall?</p>
</blockquote>
<p>hmm I'm not sure, I think we'd need <code>WalkDir</code> to return paths with a trailing slash ?</p>



<a name="160572664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160572664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160572664">(Mar 12 2019 at 14:04)</a>:</h4>
<p>I have been working on this and experimented with various tweaks to the API. Currently the callback is called in <code>Roots::contains</code> where previously <code>is_excluded</code> and <code>rel_path</code> were called with some additional parameters.</p>
<p>An example of a callback:</p>
<div class="codehilite"><pre><span></span><span class="k">fn</span> <span class="nf">include_rust_files</span><span class="p">(</span><span class="n">path</span>: <span class="nc">RootRelativePath</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Inclusion</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">const</span><span class="w"> </span><span class="n">IGNORED_FOLDERS</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="o">&amp;</span><span class="kt">str</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="p">[</span><span class="w"></span>
<span class="w">        </span><span class="s">&quot;node_modules&quot;</span><span class="p">,</span><span class="w"></span>
<span class="w">        </span><span class="s">&quot;.git&quot;</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="p">];</span><span class="w"></span>

<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">is_ignored</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">path</span><span class="p">.</span><span class="n">components</span><span class="p">()</span><span class="w"></span>
<span class="w">        </span><span class="p">.</span><span class="n">any</span><span class="p">(</span><span class="o">|</span><span class="n">c</span><span class="o">|</span><span class="w"> </span><span class="n">IGNORED_FOLDERS</span><span class="p">.</span><span class="n">contains</span><span class="p">(</span><span class="o">&amp;</span><span class="n">c</span><span class="p">.</span><span class="n">as_str</span><span class="p">()))</span><span class="w"></span>
<span class="w">        </span><span class="p">;</span><span class="w"></span>

<span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="n">is_ignored</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="n">Inclusion</span>::<span class="n">Exclude</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="c1">// Allow rust files</span>
<span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="s">&quot;rs&quot;</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">path</span><span class="p">.</span><span class="n">extension</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="n">Inclusion</span>::<span class="n">IncludeIfFile</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="c1">// TODO: This should be the default unless otherwise specified</span>
<span class="w">    </span><span class="c1">// because if you exclude here, then you won&#39;t get the nested</span>
<span class="w">    </span><span class="c1">// files under the root processed, even if they are not directly ignored</span>
<span class="w">    </span><span class="n">Inclusion</span>::<span class="n">IncludeIfDir</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p><code>RootRelativePath</code> is a container struct to allow access to the various parts of the path.</p>
<div class="codehilite"><pre><span></span><span class="sd">/// RootRelativePath identifies a file or a folder inside the root</span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">RootRelativePath</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="sd">/// The root path</span>
<span class="w">    </span><span class="n">root</span>: <span class="kp">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="n">Path</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="sd">/// The full path to the file / folder, includes the root</span>
<span class="w">    </span><span class="n">full</span>: <span class="kp">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="n">Path</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="sd">/// Relative path to root, e.g. full_path without the root as prefix</span>
<span class="w">    </span><span class="n">relative</span>: <span class="kp">&amp;</span><span class="na">&#39;a</span><span class="w"> </span><span class="n">RelativePath</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>One issue I have is that the callbacks return value is important in ways that may not be obvious, basically if you by default return <code>Inclusion::Exclude</code>, nested folders under the particular root will not be processed (if they were not roots themselves).</p>
<p>So if you have a folder structure like</p>
<div class="codehilite"><pre><span></span><span class="s">&quot;a/nested&quot;</span><span class="w"></span>
<span class="s">&quot;a/other&quot;</span><span class="w"></span>
<span class="s">&quot;a/.git&quot;</span><span class="w"></span>
</pre></div>


<p>And the <code>a</code> is used as a root, if you return <code>Inclusion::Exclude</code> from the callback, all files under the <code>nested</code>, <code>other</code> folders will not be processed even if you did not explicitly ignore them.</p>



<a name="160572988"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160572988" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160572988">(Mar 12 2019 at 14:08)</a>:</h4>
<p>Perhaps we could use a trait with two methods instead:</p>
<div class="codehilite"><pre><span></span>trait Filter {
    fn contains_path() -&gt; bool;
    fn contains_file() -&gt; bool;
}
</pre></div>


<p>?</p>



<a name="160573051"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160573051" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160573051">(Mar 12 2019 at 14:09)</a>:</h4>
<div class="codehilite"><pre><span></span>/// The full path to the file / folder, includes the root
</pre></div>


<p>I hope we could avoid exposing <code>Path/PathBuf</code> in the API, b/c they are OS-dependent</p>



<a name="160573224"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160573224" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160573224">(Mar 12 2019 at 14:11)</a>:</h4>
<p>Yeah currently they are private but used to perform checks</p>
<div class="codehilite"><pre><span></span><span class="k">impl</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="o">&gt;</span><span class="w"> </span><span class="n">RootRelativePath</span><span class="o">&lt;</span><span class="na">&#39;a</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="sd">/// Returns whether the `full_path` exists on disk and is pointing at a regular file.</span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">is_file</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">bool</span> <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="bp">self</span><span class="p">.</span><span class="n">full</span><span class="p">.</span><span class="n">is_file</span><span class="p">()</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="sd">/// Returns whether the `full_path` exists on disk and is pointing at a directory.</span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">is_dir</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">bool</span> <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="bp">self</span><span class="p">.</span><span class="n">full</span><span class="p">.</span><span class="n">is_dir</span><span class="p">()</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="160573432"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160573432" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160573432">(Mar 12 2019 at 14:13)</a>:</h4>
<blockquote>
<p>Perhaps we could use a trait with two methods instead:</p>
<p>trait Filter {<br>
    fn contains_path() -&gt; bool;<br>
    fn contains_file() -&gt; bool;<br>
}</p>
</blockquote>
<p>Use the trait instead of a function callback ?</p>



<a name="160574194"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160574194" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160574194">(Mar 12 2019 at 14:22)</a>:</h4>
<p>Yeah</p>



<a name="160574291"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160574291" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160574291">(Mar 12 2019 at 14:24)</a>:</h4>
<p>That might work, I'll experiment a bit</p>



<a name="160882652"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160882652" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160882652">(Mar 15 2019 at 15:00)</a>:</h4>
<p>An interesting "problem" came up,  if <code>Vfs::add_file_overlay</code> is called for a file, and the file does not exist, we can't properly filter it using file filtering, since when we are filtering, we can't really know if path points to a file or a directory, if it doesn't actually exist on disk yet. So</p>
<div class="codehilite"><pre><span></span><span class="n">vfs</span><span class="p">.</span><span class="n">add_file_overlay</span><span class="p">(</span><span class="o">&amp;</span><span class="n">dir</span><span class="p">.</span><span class="n">path</span><span class="p">().</span><span class="n">join</span><span class="p">(</span><span class="s">&quot;a/LICENSE2&quot;</span><span class="p">),</span><span class="w"> </span><span class="s">&quot;text&quot;</span><span class="p">.</span><span class="n">to_string</span><span class="p">());</span><span class="w"></span>
</pre></div>


<p>Would be filtered as it was a directory</p>



<a name="160913940"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160913940" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160913940">(Mar 15 2019 at 21:10)</a>:</h4>
<p>hm, if you call <code>add_file</code>, the contract is that it is a file</p>



<a name="160913958"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/160913958" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#160913958">(Mar 15 2019 at 21:10)</a>:</h4>
<p>we don't need to care about the state of the file system at all I think?</p>



<a name="161037082"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161037082" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161037082">(Mar 18 2019 at 07:40)</a>:</h4>
<p>Had some time to work on this again, I think I'm getting somewhere now. Basically we can avoid doing any extra IO when doing the filtering. By adding a new crate-specific enum for FileType, which is then used as an additional parameter to <code>Roots::find(&amp;self, path: &amp;Path, expected: FileType)</code> and <code>Roots::contains(&amp;self, root: VfsRoot, path: &amp;Path, expected: FileType)</code>. Basically <code>Vfs</code> is always expecting a <code>File</code> and <code>io</code> then provides the argument based on the actual type in the filesystem. This way we can run the correct <code>Filter</code> function based on the expectation.</p>
<p>This means that when one of the <code>_file_overlay</code> functions is called, we won't add them to the VFS unless they pass filtering, even if they don't actually exist in the filesystem yet.</p>
<p><em>NOTE</em> The <code>FileType</code> enum is purely for convenience.</p>
<div class="codehilite"><pre><span></span><span class="k">pub</span><span class="p">(</span><span class="k">crate</span><span class="p">)</span><span class="w"> </span><span class="k">enum</span> <span class="nc">FileType</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">File</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">Dir</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>Example of a filter:</p>
<div class="codehilite"><pre><span></span><span class="k">struct</span> <span class="nc">IncludeRustFiles</span><span class="p">;</span><span class="w"></span>

<span class="k">impl</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">IncludeRustFiles</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">include_folder</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">folder_path</span>: <span class="kp">&amp;</span><span class="nc">RelativePath</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">bool</span> <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">const</span><span class="w"> </span><span class="n">IGNORED_FOLDERS</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="o">&amp;</span><span class="kt">str</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="p">[</span><span class="w"></span>
<span class="w">            </span><span class="s">&quot;node_modules&quot;</span><span class="p">,</span><span class="w"></span>
<span class="w">            </span><span class="s">&quot;.git&quot;</span><span class="p">,</span><span class="w"></span>
<span class="w">        </span><span class="p">];</span><span class="w"></span>

<span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">is_ignored</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">folder_path</span><span class="p">.</span><span class="n">components</span><span class="p">()</span><span class="w"></span>
<span class="w">            </span><span class="p">.</span><span class="n">any</span><span class="p">(</span><span class="o">|</span><span class="n">c</span><span class="o">|</span><span class="w"> </span><span class="n">IGNORED_FOLDERS</span><span class="p">.</span><span class="n">contains</span><span class="p">(</span><span class="o">&amp;</span><span class="n">c</span><span class="p">.</span><span class="n">as_str</span><span class="p">()))</span><span class="w"></span>
<span class="w">            </span><span class="p">;</span><span class="w"></span>

<span class="w">        </span><span class="o">!</span><span class="n">is_ignored</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="k">fn</span> <span class="nf">include_file</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">file_path</span>: <span class="kp">&amp;</span><span class="nc">RelativePath</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">bool</span> <span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">file_path</span><span class="p">.</span><span class="n">extension</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="s">&quot;rs&quot;</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="161039198"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161039198" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161039198">(Mar 18 2019 at 08:29)</a>:</h4>
<p>Looks reasonable, I don't see any problems with this approach!</p>



<a name="161042762"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161042762" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161042762">(Mar 18 2019 at 09:39)</a>:</h4>
<p>I'm not sure what is the appropriate bound for the <code>Filter</code> when creating a <code>RootEntry</code>.</p>
<p>Currently <code>Filter</code> and <code>RootEntry</code> look like</p>
<div class="codehilite"><pre><span></span><span class="k">pub</span><span class="w"> </span><span class="k">trait</span><span class="w"> </span><span class="n">Filter</span>: <span class="nb">Send</span> <span class="o">+</span><span class="w"> </span><span class="nb">Sync</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">include_folder</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">folder_path</span>: <span class="kp">&amp;</span><span class="nc">RelativePath</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">bool</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="k">fn</span> <span class="nf">include_file</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">file_path</span>: <span class="kp">&amp;</span><span class="nc">RelativePath</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">bool</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="cp">#[derive(Clone)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">RootEntry</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">path</span>: <span class="nc">PathBuf</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">filter</span>: <span class="nc">Arc</span><span class="o">&lt;</span><span class="n">dyn</span><span class="w"> </span><span class="n">Filter</span><span class="o">&gt;</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">impl</span><span class="w"> </span><span class="n">RootEntry</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">new</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">path</span>: <span class="nc">PathBuf</span><span class="p">,</span><span class="w"> </span><span class="n">filter</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"></span>
<span class="w">    </span><span class="k">where</span><span class="w"></span>
<span class="w">        </span><span class="n">T</span>: <span class="nc">Filter</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">&#39;static</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">RootEntry</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">path</span><span class="p">,</span><span class="w"> </span><span class="n">filter</span>: <span class="nc">Arc</span>::<span class="n">new</span><span class="p">(</span><span class="n">filter</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>


<p>This means that each <code>RootEntry::new</code> will create a new <code>Arc</code>. But I'm not sure adding a function that takes an <code>Arc&lt;dyn Filter&gt;</code> is appropriate?</p>



<a name="161042934"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161042934" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161042934">(Mar 18 2019 at 09:42)</a>:</h4>
<p><code>Send + Sync</code> bounds on <code>Filter</code> sounds right to me.</p>
<p>API-wise, we should accept an <code>Box&lt;dyn Filter&gt;</code> and convert it to <code>Arc&lt;dyn Filter&gt;</code> internally (via <code>Into</code>). Though, I am not sure if we need <code>Arc</code> at all here: I think <code>Root</code> could store just <code>Box</code>, iirc, we already put roots inside arcs?</p>



<a name="161043030"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161043030" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161043030">(Mar 18 2019 at 09:44)</a>:</h4>
<p>Roots are inside arcs but the way <code>Roots</code> is currently initialized, we <code>clone</code> the entry</p>



<a name="161043101"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161043101" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161043101">(Mar 18 2019 at 09:45)</a>:</h4>
<p>Although I suppose the clone could be avoided by restructuring the <code>Roots::new</code> a bit</p>



<a name="161055820"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161055820" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161055820">(Mar 18 2019 at 13:13)</a>:</h4>
<p>Now the <code>RootEntry</code> contains <code>Box&lt;dyn Filter&gt;</code> with no extra <code>Arc</code> or cloning happening. Is there a reason to accept only <code>Box&lt;dyn Filter&gt;</code> vs adding a trait bound ?</p>
<div class="codehilite"><pre><span></span><span class="k">impl</span><span class="w"> </span><span class="n">RootEntry</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">new</span><span class="p">(</span><span class="n">path</span>: <span class="nc">PathBuf</span><span class="p">,</span><span class="w"> </span><span class="n">filter</span>: <span class="nb">Box</span><span class="o">&lt;</span><span class="n">dyn</span><span class="w"> </span><span class="n">Filter</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">RootEntry</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">path</span><span class="p">,</span><span class="w"> </span><span class="n">filter</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">new_alt</span><span class="p">(</span><span class="n">path</span>: <span class="nc">PathBuf</span><span class="p">,</span><span class="w"> </span><span class="n">filter</span>: <span class="nc">impl</span><span class="w"> </span><span class="n">Filter</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">&#39;static</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">RootEntry</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">path</span><span class="p">,</span><span class="w"> </span><span class="n">filter</span>: <span class="nb">Box</span>::<span class="n">new</span><span class="p">(</span><span class="n">filter</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>



<a name="161061481"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161061481" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161061481">(Mar 18 2019 at 14:25)</a>:</h4>
<p>PR Up in <a href="https://github.com/rust-analyzer/ra_vfs/pull/4" target="_blank" title="https://github.com/rust-analyzer/ra_vfs/pull/4">https://github.com/rust-analyzer/ra_vfs/pull/4</a></p>



<a name="161139296"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161139296" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161139296">(Mar 19 2019 at 10:52)</a>:</h4>
<p>I was thinking about filtering examples etc from external crates, the best place to do this is probably <code>ra_project_model</code> ? Instead of <code>ProjectWorkspace::to_roots</code> returning a <code>Vec&lt;PathBuf&gt;</code>, we could return <code>Vec&lt;ra_vfs::RootEntry&gt;</code> where the filter has knowledge on if its an external crate or a member of the current project. This would mean adding <code>ra_vfs</code> dependency to <code>ra_project_model</code> though</p>



<a name="161176263"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161176263" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161176263">(Mar 19 2019 at 18:14)</a>:</h4>
<p>argh........</p>
<p>I've just remembered the reason why I wanted to stick with <code>Fn(&amp;RelativePathBuf)</code> interafact for filtering, instead of introducing a nominal trait</p>



<a name="161176334"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161176334" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161176334">(Mar 19 2019 at 18:15)</a>:</h4>
<p>:)</p>
<p>I think it would be nice to avoid depndency on vfs though. Can project module supply something which could be converted to ra_vfs::RootEntry easily by a third crate?</p>



<a name="161176454"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161176454" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161176454">(Mar 19 2019 at 18:17)</a>:</h4>
<p>Hmm should be doable</p>



<a name="161176552"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161176552" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161176552">(Mar 19 2019 at 18:18)</a>:</h4>
<blockquote>
<p>argh........</p>
<p>I've just remembered the reason why I wanted to stick with <code>Fn(&amp;RelativePathBuf)</code> interafact for filtering, instead of introducing a nominal trait</p>
</blockquote>
<p>what's the reason ?</p>



<a name="161176778"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161176778" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161176778">(Mar 19 2019 at 18:21)</a>:</h4>
<p>to not depend on <code>vfs</code> :)</p>



<a name="161176830"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161176830" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161176830">(Mar 19 2019 at 18:21)</a>:</h4>
<p>If the type is non-nominal (like a tuple of <code>Fn</code>s or something), two crates can agree on it without depending on each other.</p>



<a name="161176907"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161176907" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161176907">(Mar 19 2019 at 18:22)</a>:</h4>
<p>Ah, yes of course</p>



<a name="161176969"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161176969" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161176969">(Mar 19 2019 at 18:23)</a>:</h4>
<p>I think the <code>ra_project_mode</code> can return just some tuple for example with  <code>(PathBuf, is_member)</code> that can then be used outside of it</p>



<a name="161177055"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161177055" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161177055">(Mar 19 2019 at 18:24)</a>:</h4>
<p>yeah, something like that should work</p>



<a name="161177096"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161177096" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161177096">(Mar 19 2019 at 18:24)</a>:</h4>
<p>I'd still like to combine the Filter somewhere, since both <code>ra_batch</code> and the lsp server are using the roots</p>



<a name="161221372"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161221372" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161221372">(Mar 20 2019 at 07:11)</a>:</h4>
<p>hmm, do we have more common functionality that could be shared between crates ? I was thinking about creating a simple crate <code>vfs_filter</code> or <code>ra_filter</code> or some such that would depend on <code>Vfs</code> and then both <code>ra_lsp_server</code> and <code>ra_batch</code> could depend on it. The new crate would contain the filters and such.<br>
But if we have more common functionality, maybe creating <code>ra_common</code> could be useful ?</p>



<a name="161221949"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161221949" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> matklad <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161221949">(Mar 20 2019 at 07:24)</a>:</h4>
<p>My gut feeling is that we don't actually want to share anything between these filters. It might turn out not to be true, we'll see, but, at this point, I think it's easier to keep the <em>logic</em> inside project_model, and provide a thin vfs glue twice, in ra_batch and ra_lsp_server</p>



<a name="161222090"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161222090" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161222090">(Mar 20 2019 at 07:27)</a>:</h4>
<p>Actually that sounds reasonable, so <code>project_model</code> returns something that allows us to tell if a root is part of the current workspace or not, then both <code>ra_lsp_server</code> and <code>ra_batch</code> implement their own Filters, which initially can be similar but may end up being different ?</p>



<a name="161230790"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/185405-t-compiler/rust-analyzer/topic/ignoring%20in%20VFS/near/161230790" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> vipentti <a href="https://rust-lang.github.io/zulip_archive/stream/185405-t-compiler/rust-analyzer/topic/ignoring.20in.20VFS.html#161230790">(Mar 20 2019 at 09:59)</a>:</h4>
<p>Updated the pr <a href="https://github.com/rust-analyzer/rust-analyzer/pull/997" target="_blank" title="https://github.com/rust-analyzer/rust-analyzer/pull/997">https://github.com/rust-analyzer/rust-analyzer/pull/997</a></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>